package com.shuiyun.jtt.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.crypto.asymmetric.RSA;
import com.shuiyun.jtt.entity.form.T0800Form;
import com.shuiyun.jtt.entity.form.T0900Form;
import com.shuiyun.jtt.enums.JT808;
import com.shuiyun.jtt.message.JTMessage;
import com.shuiyun.jtt.message.jt808.*;
import com.shuiyun.jtt.message.jt808.extend.AddLocation;
import com.shuiyun.jtt.message.jt808.extend.CanInfo;
import com.shuiyun.jtt.server.ClientServer;
import com.shuiyun.jtt.session.Session;
import com.shuiyun.jtt.thread.HeartbeatThead;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author shuiyun
 * @description 测试接口
 * @date 2022-04-16 16:53
 */
@Slf4j
@Api(tags = "测试接口")
@RestController
@RequestMapping("test")
public class TestController {
    private final AtomicInteger serialNo = new AtomicInteger(0);

    private final ClientServer clientServer;

    public TestController(ClientServer clientServer) {
        this.clientServer = clientServer;
    }

    private final String mobileNumber = "14455521231";


    @GetMapping
    @ApiOperation("测试接口")
    public String test() {
        return "shuiyun";
    }

    @ApiOperation("注册接口")
    @PostMapping("/register")
    public String register(@RequestBody T0100 message) {
        message.setHeader(JT808.终端注册0x0100, mobileNumber, serialNo.incrementAndGet());
        clientServer.getChannel().writeAndFlush(message);
        return "ok" + DateUtil.now();
    }

    @ApiOperation("终端鉴权")
    @PostMapping("/auth")
    public String auth(@RequestBody T0102 message) {
        message.setHeader(JT808.终端鉴权0x0102, mobileNumber, serialNo.incrementAndGet());
        clientServer.getChannel().writeAndFlush(message);
        // 启动异步线程发送心跳信息
        new HeartbeatThead(clientServer.getChannel(), mobileNumber).start();
        return "ok" + DateUtil.now();
    }

    @ApiOperation("获取服务器时间")
    @GetMapping("/serverTime")
    public String getServerTime() {
        JTMessage message = new JTMessage();
        message.setHeader(JT808.查询服务器时间0x0004, mobileNumber, serialNo.incrementAndGet());
        clientServer.getChannel().writeAndFlush(message);
        return "ok" + DateUtil.now();
    }


    @ApiOperation("定位信息")
    @PostMapping("/location")
    public String location(@RequestBody T0200 message) {
        message.setHeader(JT808.位置信息汇报0x0200, mobileNumber, serialNo.incrementAndGet());
        clientServer.getChannel().writeAndFlush(message);
        return "ok" + DateUtil.now();
    }

    @GetMapping("/waybill")
    @ApiOperation("电子运单")
    public String waybill(String waybill) {
        T0701 t0701 = new T0701();
        t0701.setWaybill(waybill);
        t0701.setHeader(JT808.电子运单上报0x0701, mobileNumber, serialNo.getAndIncrement());
        clientServer.getChannel().writeAndFlush(t0701);
        return "ok" + DateUtil.now();
    }

    @GetMapping("/locations")
    @ApiOperation("批量定位数据上行")
    public String locations() {
        T0704 t0704 = new T0704();
        t0704.setHeader(JT808.定位数据批量上传0x0704, mobileNumber, serialNo.getAndIncrement());
        t0704.setType(0);
        List<AddLocation> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            T0200 location = new T0200(0, 3, 30554380, 104064048, 420, 80, 10, new Date(), null);
            list.add(new AddLocation(location));
        }
        t0704.setSize(list.size());
        t0704.setAddLocationList(list);
        clientServer.getChannel().writeAndFlush(t0704);
        return "ok" + DateUtil.now();
    }

    @GetMapping("/can")
    @ApiOperation("can数据上报")
    public String can() {
        T0705 t0705 = new T0705();
        t0705.setHeader(JT808.CAN总线数据上传0x0705, mobileNumber, serialNo.getAndIncrement());
        t0705.setTime("2345101234");
        List<CanInfo> list = new ArrayList<>();
        byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};

        // bit30 0:标准帧 bit31 0：can1

        for (int i = 0; i < 10; i++) {
            CanInfo canInfo = new CanInfo(i, bytes);
            list.add(canInfo);
        }
        t0705.setSize(list.size());
        t0705.setList(list);
        clientServer.getChannel().writeAndFlush(t0705);
        return "ok" + DateUtil.now();
    }

    @PostMapping("/t0800")
    @ApiOperation("多媒体事件信息上传")
    public String t0800(@RequestBody T0800Form form) {
        T0800 t0800 = BeanUtil.copyProperties(form, T0800.class);
        t0800.setHeader(JT808.多媒体事件信息上传0x0800, mobileNumber, serialNo.getAndIncrement());
        clientServer.getChannel().writeAndFlush(t0800);
        return "ok" + DateUtil.now();
    }

    @PutMapping("/t0801")
    @ApiOperation("多媒体事件信息上传 - 携带文件")
    public String t0800(T0800Form form, @RequestParam("file") MultipartFile file) {
        T0801 t0801 = BeanUtil.copyProperties(form, T0801.class);
        t0801.setLocation(new T0200(0, 3, 30554380, 104064048, 420, 80, 10, new Date(), null));
        try (InputStream inputStream = file.getInputStream();
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ) {
            IoUtil.copy(inputStream, outputStream);
            byte[] bytes = outputStream.toByteArray();
            t0801.setBytes(bytes);
        } catch (Exception e) {
            return "error";
        }
        t0801.setHeader(JT808.多媒体数据上传0x0801, mobileNumber, serialNo.getAndIncrement());
        clientServer.getChannel().writeAndFlush(t0801);
        return "ok" + DateUtil.now();
    }

    @PostMapping("/t0900")
    @ApiOperation("消息透传上行")
    public String t0900(@RequestBody T0900Form form) {
        T0900 t0900 = BeanUtil.copyProperties(form, T0900.class);
        t0900.setHeader(JT808.数据上行透传0x0900, mobileNumber, serialNo.getAndIncrement());
        clientServer.getChannel().writeAndFlush(t0900);
        return "ok" + DateUtil.now();
    }

    @PutMapping("/t0901")
    @ApiOperation("数据压缩上报")
    public String t0901(String content) {
        byte[] bytes = ZipUtil.gzip(content, "GBK");
        T0901 t0901 = new T0901(bytes);
        t0901.setHeader(JT808.数据压缩上报0x0901, mobileNumber, serialNo.getAndIncrement());
        clientServer.getChannel().writeAndFlush(t0901);
        return "ok" + DateUtil.now();
    }

    @PutMapping("/t0a00")
    @ApiOperation("终端RAS秘钥")
    public String t0a00() {
        T0A00 t0A00 = new T0A00(RandomUtil.randomInt(141436958), RandomUtil.randomBytes(128));
        t0A00.setHeader(JT808.终端RSA公钥0x0A00, mobileNumber, serialNo.getAndIncrement());
        clientServer.getChannel().writeAndFlush(t0A00);
        return "ok" + DateUtil.now();
    }


}
